﻿using System;
using System.Collections;
using System.Xml;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Worker;

namespace InfoJetSoft.Service.Util
{
	
	public class NamespaceResolver : XmlNamespaceManager
	{
		//这两个Hashtable为InfoJet Service使用,和XPath的功能无关.
		//GetPrefix()和GetURI()也不是XmlNamespaceManager的重载方法.
		private Hashtable prefixTable = null;
		private Hashtable uriTable = null;
		
		public NamespaceResolver(XmlDocument doc):base(doc.NameTable)
		{
			this.prefixTable = new Hashtable();
			this.uriTable = new Hashtable();
			this.buildNamespaces(doc);
			//添加msxsl Namespace,有些情况需要这个Namespace.
			if( !this.prefixTable.ContainsKey( "msxsl" ) )
			{
				this.prefixTable.Add( "msxsl", JetConstant.URI_XDMSXSL );
				HashtableUtil.addSafety( this.uriTable, JetConstant.URI_XDMSXSL, "msxml" );
			}
			if( !this.HasNamespace( "msxsl" ) )
			{
				this.AddNamespace( "msxsl", JetConstant.URI_XDMSXSL );
			}
		}
		
		private void buildNamespaces(XmlDocument doc)
		{
            XmlElement root = doc.DocumentElement;
			if( root == null )
			{
				return;
			}
			XmlNodeList elementList = root.SelectNodes( "//*" );
			foreach( XmlElement element in elementList ){
				this.AddNamespace( element.Prefix , element.NamespaceURI );
                foreach( XmlAttribute attribute in element.Attributes )
				{
					if( attribute.Name.Equals( "xmlns" ) && attribute.Value.Equals( "" ) )
					{
						continue;
					}
					if( attribute.Prefix.Equals( "xmlns" ) || attribute.LocalName.Equals( "xmlns" ) )
					{
						if( !this.prefixTable.ContainsKey( attribute.LocalName ) )
						{
							this.prefixTable.Add( attribute.LocalName , attribute.Value );
							HashtableUtil.addSafety( this.uriTable, attribute.Value, attribute.LocalName );
							if( !attribute.LocalName.ToLower().StartsWith( "xml" ) )
							{
								this.AddNamespace( attribute.LocalName , attribute.Value );
							}
						}
					}
				}
			}
		}

		//CID 0418 //2009.10.08 //Begin
		public void unifyNamespaces( Manifest manifest )
		{
			foreach( XmlAttribute attribute in manifest.Doc.DocumentElement.Attributes )
			{
				if( attribute.Name.Equals( "xmlns" ) && attribute.Value.Equals( "" ) )
				{
					continue;
				}
				if( attribute.Prefix.Equals( "xmlns" ) || attribute.LocalName.Equals( "xmlns" ) )
				{
					//只需要向XmlNamespaceManager中添加Namespace,并替换原来的.
					if( !attribute.LocalName.ToLower().StartsWith( "xml" ) )
					{
						this.AddNamespace( attribute.LocalName , attribute.Value );
					}
				}
			}
		}
		//CID 0418 //2009.10.08 //End

		public string GetPrefix( string uri )
		{
			return (string) this.uriTable[ uri ];
		}

		public string GetURI( string prefix ){
			return (string) this.prefixTable[ prefix ];
		}

	}
}